package org.example.exampreparationtreasure.service.impl;

import org.example.exampreparationtreasure.common.BusinessException;
import org.example.exampreparationtreasure.common.CommonResultStatus;
import org.example.exampreparationtreasure.mapper.*;
import org.example.exampreparationtreasure.model.entity.Question;
import org.example.exampreparationtreasure.model.entity.QuestionCategory; // 确保导入
import org.example.exampreparationtreasure.model.vo.PreferenceRequest;
import org.example.exampreparationtreasure.model.vo.RecommendationHistoryResponse;
import org.example.exampreparationtreasure.model.vo.StudyPlanResponse;
import org.example.exampreparationtreasure.service.RecommendationService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 推荐系统服务实现 - 基于真实数据
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RecommendationServiceImpl implements RecommendationService {

    private final QuestionMapper questionMapper;
    private final RecommendationMapper recommendationMapper;
    private final QuestionCategoryMapper questionCategoryMapper;

    @Override
    public List<Question> getRecommendedQuestions(Long userId, List<Long> includeCategoryIds, Integer size) {
        log.info("获取用户{}的推荐题目，分类ID：{}，数量：{}", userId, includeCategoryIds, size);

        try {
            // 参数验证
            if (userId == null) {
                throw new BusinessException(CommonResultStatus.PARAM_ERROR, "用户ID不能为空");
            }
            if (size == null || size <= 0) {
                size = 10;
            }

            List<Long> questionIds;

            try {
                // 1. 尝试获取用户的薄弱分类
                log.info("开始查询用户{}的薄弱分类", userId);
                List<Long> weakCategoryIds = recommendationMapper.selectWeakCategoryIdsByUserId(userId);
                log.info("用户{}的薄弱分类查询成功：{}", userId, weakCategoryIds);

                // 2. 确定最终要查询的分类
                List<Long> targetCategoryIds = determineTargetCategories(includeCategoryIds, weakCategoryIds);
                log.info("目标分类确定：{}", targetCategoryIds);

                // 3. 获取推荐题目ID（目前不按难度过滤，后续可以扩展）
                log.info("开始查询推荐题目ID，targetCategoryIds：{}，size：{}", targetCategoryIds, size);
                questionIds = recommendationMapper.selectRecommendedQuestionIds(targetCategoryIds, size);
                log.info("推荐题目ID查询成功：{}", questionIds);

            } catch (Exception e) {
                log.warn("基于分类的推荐失败，使用随机推荐：{}", e.getMessage());
                // 如果基于分类的推荐失败，使用随机推荐
                questionIds = recommendationMapper.selectRandomQuestionIds(size);
                log.info("随机推荐题目ID：{}", questionIds);
            }

            // 4. 查询完整的题目信息
            List<Question> result = new ArrayList<>();
            if (!questionIds.isEmpty()) {
                LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(Question::getQuestionId, questionIds);
                result = questionMapper.selectList(queryWrapper);
                log.info("题目详细信息查询成功，共{}道题目", result.size());
            } else {
                log.warn("没有找到推荐题目ID，返回空列表");
            }

            log.info("为用户{}推荐了{}道题目", userId, result.size());
            return result;

        } catch (Exception e) {
            log.error("获取推荐题目失败，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            throw new BusinessException(CommonResultStatus.SERVER_ERROR, "获取推荐题目失败：" + e.getMessage());
        }
    }

    @Override
    public StudyPlanResponse generateStudyPlan(Long userId) {
        log.info("为用户{}生成个性化学习计划", userId);

        try {
            if (userId == null) {
                throw new BusinessException(CommonResultStatus.PARAM_ERROR, "用户ID不能为空");
            }

            // 1. 获取用户数据
            log.info("开始获取用户{}的薄弱分类", userId);
            List<Long> weakCategoryIds;
            try {
                weakCategoryIds = recommendationMapper.selectWeakCategoryIdsByUserId(userId);
                log.info("用户{}的薄弱分类查询成功：{}", userId, weakCategoryIds);
            } catch (Exception e) {
                log.warn("获取用户{}的薄弱分类失败，使用空列表：{}", userId, e.getMessage());
                weakCategoryIds = new ArrayList<>();
            }

            log.info("开始获取用户{}的答题统计", userId);
            RecommendationMapper.UserAnswerStats answerStats;
            try {
                answerStats = recommendationMapper.selectUserAnswerStats(userId);
                log.info("用户{}的答题统计查询成功：{}", userId, answerStats);
            } catch (Exception e) {
                log.warn("获取用户{}的答题统计失败，使用默认值：{}", userId, e.getMessage());
                answerStats = null;
            }

            // 2. 构建学习计划
            log.info("开始构建学习计划");
            StudyPlanResponse plan = new StudyPlanResponse();
            plan.setUserId(userId);
            plan.setPlanName("个性化学习计划");
            plan.setDescription("基于您的学习历史和薄弱环节制定的个性化学习计划");
            plan.setStartDate(LocalDateTime.now());
            plan.setEndDate(LocalDateTime.now().plusDays(30));
            plan.setAccuracyRate(answerStats != null ? answerStats.getAccuracyRate() : 0.0);

            // 3. 创建学习阶段
            log.info("开始创建学习阶段");
            List<StudyPlanResponse.StudyPhase> phases = createPersonalizedStudyPhases(weakCategoryIds, answerStats);
            plan.setPhases(phases);

            // 4. 计算统计数据
            int totalQuestions = phases.stream().mapToInt(StudyPlanResponse.StudyPhase::getQuestionCount).sum();
            int estimatedHours = phases.stream().mapToInt(StudyPlanResponse.StudyPhase::getEstimatedDays).sum() * 2;

            plan.setTotalQuestions(totalQuestions);
            plan.setEstimatedHours(estimatedHours);
            plan.setWeakCategoryCount(weakCategoryIds.size());

            log.info("为用户{}生成了包含{}个阶段的学习计划，总计{}道题目", userId, phases.size(), totalQuestions);
            return plan;

        } catch (Exception e) {
            log.error("生成学习计划失败，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            throw new BusinessException(CommonResultStatus.SERVER_ERROR, "生成学习计划失败：" + e.getMessage());
        }
    }

    @Override
    public void updateUserPreference(Long userId, PreferenceRequest preference) {
        log.info("更新用户{}的推荐偏好", userId);

        try {
            if (userId == null) {
                throw new BusinessException(CommonResultStatus.PARAM_ERROR, "用户ID不能为空");
            }

            validatePreference(preference);
            // TODO: 实现偏好保存逻辑
            log.info("用户{}偏好更新成功", userId);
        } catch (Exception e) {
            log.error("更新用户偏好失败，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            throw new BusinessException(CommonResultStatus.SERVER_ERROR, "更新用户偏好失败：" + e.getMessage());
        }
    }

    @Override
    public RecommendationHistoryResponse getRecommendationHistory(Long userId) {
        log.info("获取用户{}的推荐历史", userId);

        try {
            if (userId == null) {
                throw new BusinessException(CommonResultStatus.PARAM_ERROR, "用户ID不能为空");
            }

            RecommendationHistoryResponse history = new RecommendationHistoryResponse();
            history.setUserId(userId);

            // TODO: 从数据库查询真实的推荐历史
            List<RecommendationHistoryResponse.RecommendationRecord> records = generateMockHistory();
            history.setRecords(records);
            history.setTotalCount(records.size());

            log.info("获取用户{}的推荐历史成功，共{}条记录", userId, records.size());
            return history;
        } catch (Exception e) {
            log.error("获取推荐历史失败，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            throw new BusinessException(CommonResultStatus.SERVER_ERROR, "获取推荐历史失败：" + e.getMessage());
        }
    }

    @Override
    public void recordRecommendationHistory(Long userId, List<Question> questions) {
        log.info("记录用户{}的推荐历史，题目数量：{}", userId, questions != null ? questions.size() : 0);

        if (userId == null || questions == null || questions.isEmpty()) {
            return;
        }

        // TODO: 实现推荐历史记录逻辑
        log.debug("推荐历史记录完成");
    }

    /**
     * 确定目标分类
     */
    private List<Long> determineTargetCategories(List<Long> includeCategoryIds, List<Long> weakCategoryIds) {
        if (includeCategoryIds != null && !includeCategoryIds.isEmpty()) {
            // 用户指定了分类，优先使用薄弱分类与指定分类的交集
            List<Long> intersection = includeCategoryIds.stream()
                    .filter(weakCategoryIds::contains)
                    .collect(Collectors.toList());
            return !intersection.isEmpty() ? intersection : includeCategoryIds;
        } else {
            // 用户未指定分类，使用薄弱分类
            return !weakCategoryIds.isEmpty() ? weakCategoryIds : getAllMainCategoryIds();
        }
    }

    /**
     * 获取所有主要分类ID - 使用队友的QuestionCategoryMapper
     */
    private List<Long> getAllMainCategoryIds() {
        log.info("开始获取所有主要分类ID");
        try {
            // 使用队友的Mapper查询顶级分类（parentId = 0）
            List<QuestionCategory> topCategories = questionCategoryMapper.selectByParentId(0L);
            if (topCategories == null || topCategories.isEmpty()) {
                log.warn("未找到顶级分类，使用默认值");
                return Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
            }
            
            List<Long> categoryIds = topCategories.stream()
                    .map(QuestionCategory::getId)
                    .collect(Collectors.toList());
            log.info("获取主要分类ID成功：{}", categoryIds);
            return categoryIds;
        } catch (Exception e) {
            log.error("获取分类ID失败，使用默认值：{}", e.getMessage(), e);
            return Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
        }
    }

    /**
     * 创建个性化学习阶段
     */
    private List<StudyPlanResponse.StudyPhase> createPersonalizedStudyPhases(
            List<Long> weakCategoryIds, RecommendationMapper.UserAnswerStats answerStats) {

        log.info("开始创建个性化学习阶段，weakCategoryIds：{}，answerStats：{}", weakCategoryIds, answerStats);
        
        List<StudyPlanResponse.StudyPhase> phases = new ArrayList<>();

        try {
            // 阶段1: 基础巩固（如果正确率较低）
            if (answerStats == null || answerStats.getAccuracyRate() < 70.0) {
                log.info("创建基础巩固阶段");
                StudyPlanResponse.StudyPhase basicPhase = new StudyPlanResponse.StudyPhase();
                basicPhase.setPhaseName("基础巩固");
                basicPhase.setDescription("夯实基础，提高基础题正确率");
                
                List<Long> mainCategoryIds = getAllMainCategoryIds();
                basicPhase.setCategoryIds(mainCategoryIds);
                basicPhase.setDifficultyLevel("易");
                basicPhase.setQuestionCount(40);
                basicPhase.setEstimatedDays(7);
                basicPhase.setPriority(1);
                phases.add(basicPhase);
            }

            // 阶段2: 薄弱环节专项训练
            if (!weakCategoryIds.isEmpty()) {
                log.info("创建薄弱环节专项训练阶段");
                StudyPlanResponse.StudyPhase weakPhase = new StudyPlanResponse.StudyPhase();
                weakPhase.setPhaseName("薄弱环节专项");
                weakPhase.setDescription("针对性训练薄弱知识点");
                weakPhase.setCategoryIds(weakCategoryIds);
                weakPhase.setDifficultyLevel("中");
                weakPhase.setQuestionCount(30);
                weakPhase.setEstimatedDays(10);
                weakPhase.setPriority(2);
                phases.add(weakPhase);
            }

            // 阶段3: 综合提升
            log.info("创建综合能力提升阶段");
            StudyPlanResponse.StudyPhase improvePhase = new StudyPlanResponse.StudyPhase();
            improvePhase.setPhaseName("综合能力提升");
            improvePhase.setDescription("全面提升解题能力");
            
            List<Long> mainCategoryIds = getAllMainCategoryIds();
            improvePhase.setCategoryIds(mainCategoryIds);
            improvePhase.setDifficultyLevel("中,难");
            improvePhase.setQuestionCount(50);
            improvePhase.setEstimatedDays(10);
            improvePhase.setPriority(3);
            phases.add(improvePhase);

            // 阶段4: 模拟测试
            log.info("创建模拟测试阶段");
            StudyPlanResponse.StudyPhase mockPhase = new StudyPlanResponse.StudyPhase();
            mockPhase.setPhaseName("模拟测试");
            mockPhase.setDescription("检验学习成果");
            
            List<Long> mainCategoryIds2 = getAllMainCategoryIds();
            mockPhase.setCategoryIds(mainCategoryIds2);
            mockPhase.setDifficultyLevel("易,中,难");
            mockPhase.setQuestionCount(20);
            mockPhase.setEstimatedDays(3);
            mockPhase.setPriority(4);
            phases.add(mockPhase);

            log.info("学习阶段创建完成，共{}个阶段", phases.size());
            return phases;
            
        } catch (Exception e) {
            log.error("创建学习阶段失败：{}", e.getMessage(), e);
            // 返回一个默认的学习阶段
            StudyPlanResponse.StudyPhase defaultPhase = new StudyPlanResponse.StudyPhase();
            defaultPhase.setPhaseName("默认学习计划");
            defaultPhase.setDescription("基础学习计划");
            defaultPhase.setCategoryIds(Arrays.asList(1L, 2L, 3L));
            defaultPhase.setDifficultyLevel("易");
            defaultPhase.setQuestionCount(20);
            defaultPhase.setEstimatedDays(7);
            defaultPhase.setPriority(1);
            return Arrays.asList(defaultPhase);
        }
    }

    /**
     * 验证偏好数据
     */
    private void validatePreference(PreferenceRequest preference) {
        if (preference == null) {
            throw new BusinessException(CommonResultStatus.PARAM_ERROR, "偏好设置不能为空");
        }
        if (preference.getPreferredCategories() == null || preference.getPreferredCategories().isEmpty()) {
            throw new BusinessException(CommonResultStatus.PARAM_ERROR, "偏好分类不能为空");
        }
        if (preference.getDifficultyLevel() == null || preference.getDifficultyLevel().trim().isEmpty()) {
            throw new BusinessException(CommonResultStatus.PARAM_ERROR, "难度级别不能为空");
        }
        // 验证难度级别（支持中英文格式）
        List<String> validDifficultyLevels = Arrays.asList("易", "中", "难", "easy", "medium", "hard");
        String difficulty = preference.getDifficultyLevel().trim();
        if (!validDifficultyLevels.contains(difficulty)) {
            throw new BusinessException(CommonResultStatus.PARAM_ERROR, "难度级别必须是: 易/中/难 或 easy/medium/hard");
        }
    }

    /**
     * 将英文难度转换为中文难度（数据库格式）
     */
    private String convertDifficultyToChinese(String difficulty) {
        if (difficulty == null) return null;
        switch (difficulty.toLowerCase()) {
            case "easy": return "易";
            case "medium": return "中";
            case "hard": return "难";
            case "易": return "易";
            case "中": return "中";
            case "难": return "难";
            default: return "易";
        }
    }

    @Override
    public List<Question> getRecommendedQuestionsWithPreference(Long userId, List<Long> includeCategoryIds, 
                                                                   String difficultyLevel, Integer size) {
        log.info("获取用户{}的推荐题目，分类ID：{}，难度：{}，数量：{}", userId, includeCategoryIds, difficultyLevel, size);

        try {
            // 参数验证
            if (userId == null) {
                throw new BusinessException(CommonResultStatus.PARAM_ERROR, "用户ID不能为空");
            }
            if (size == null || size <= 0) {
                size = 10;
            }

            // 转换难度格式
            String chineseDifficulty = convertDifficultyToChinese(difficultyLevel);
            log.info("难度转换：{} -> {}", difficultyLevel, chineseDifficulty);

            List<Long> questionIds;

            try {
                // 1. 尝试获取用户的薄弱分类
                log.info("开始查询用户{}的薄弱分类", userId);
                List<Long> weakCategoryIds = recommendationMapper.selectWeakCategoryIdsByUserId(userId);
                log.info("用户{}的薄弱分类查询成功：{}", userId, weakCategoryIds);

                // 2. 确定最终要查询的分类
                List<Long> targetCategoryIds = determineTargetCategories(includeCategoryIds, weakCategoryIds);
                log.info("目标分类确定：{}", targetCategoryIds);

                // 3. 获取推荐题目ID（带难度过滤）
                log.info("开始查询推荐题目ID，targetCategoryIds：{}，difficulty：{}，size：{}", 
                        targetCategoryIds, chineseDifficulty, size);
                questionIds = recommendationMapper.selectRecommendedQuestionIdsWithDifficulty(
                        targetCategoryIds, chineseDifficulty, size);
                log.info("推荐题目ID查询成功：{}", questionIds);

            } catch (Exception e) {
                log.warn("基于分类和难度的推荐失败，使用随机推荐：{}", e.getMessage());
                // 如果基于分类和难度的推荐失败，使用随机推荐
                questionIds = recommendationMapper.selectRandomQuestionIds(size);
                log.info("随机推荐题目ID：{}", questionIds);
            }

            // 4. 查询完整的题目信息
            List<Question> result = new ArrayList<>();
            if (!questionIds.isEmpty()) {
                LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(Question::getQuestionId, questionIds);
                result = questionMapper.selectList(queryWrapper);
                log.info("题目详细信息查询成功，共{}道题目", result.size());
            } else {
                log.warn("没有找到推荐题目ID，返回空列表");
            }

            log.info("为用户{}推荐了{}道题目", userId, result.size());
            return result;

        } catch (Exception e) {
            log.error("获取推荐题目失败，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            throw new BusinessException(CommonResultStatus.SERVER_ERROR, "获取推荐题目失败：" + e.getMessage());
        }
    }

    /**
     * 生成模拟历史数据
     */
    private List<RecommendationHistoryResponse.RecommendationRecord> generateMockHistory() {
        List<RecommendationHistoryResponse.RecommendationRecord> records = new ArrayList<>();

        // 模拟历史记录1
        RecommendationHistoryResponse.RecommendationRecord record1 = new RecommendationHistoryResponse.RecommendationRecord();
        record1.setRecordId(1L);
        record1.setRecommendationType("adaptive");
        record1.setQuestionIds(Arrays.asList(1L, 2L, 3L, 4L, 5L));
        record1.setCategoryIds(Arrays.asList(1L, 2L));
        record1.setDifficultyLevel("中");
        record1.setCreatedAt(LocalDateTime.now().minusDays(1));
        record1.setQuestionCount(5);
        record1.setStatus("completed");
        records.add(record1);

        // 模拟历史记录2
        RecommendationHistoryResponse.RecommendationRecord record2 = new RecommendationHistoryResponse.RecommendationRecord();
        record2.setRecordId(2L);
        record2.setRecommendationType("weakness_focused");
        record2.setQuestionIds(Arrays.asList(6L, 7L, 8L));
        record2.setCategoryIds(Arrays.asList(3L));
        record2.setDifficultyLevel("易");
        record2.setCreatedAt(LocalDateTime.now().minusHours(6));
        record2.setQuestionCount(3);
        record2.setStatus("pending");
        records.add(record2);

        return records;
    }
}